package com.feinno.urcs.group.service;

import com.feinno.urcs.dns.EnumService;
import com.feinno.urcs.group.GroupConfiguration;
import com.feinno.urcs.group.GroupError;
import com.feinno.urcs.group.GroupException;
import com.feinno.urcs.group.api.*;
import com.feinno.urcs.group.entity.*;
import com.feinno.urcs.group.interop.entity.*;
import com.feinno.urcs.group.pctask.task.*;
import com.feinno.urcs.group.pd.task.entity.*;
import com.feinno.urcs.group.siptask.task.*;
import com.feinno.urcs.mobile.UserLocatorService;
import com.feinno.urcs.mobile.entity.UserType;
import com.feinno.urcs.profile.entity.ClientType;
import com.feinno.urcs.types.MobileNo;
import com.feinno.util.StringUtils;
import org.helium.framework.annotations.ServiceImplementation;
import org.helium.framework.annotations.ServiceSetter;
import org.helium.framework.annotations.TaskEvent;
import org.helium.framework.task.TaskProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sip.address.SipURI;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Li.Hongbo <lihongbo@feinno.com>
 */
@ServiceImplementation
public class GroupServiceImpl implements GroupService {

	private static final Logger LOGGER = LoggerFactory.getLogger(GroupServiceImpl.class);
	@ServiceSetter
	private GroupDao groupDao;
	@ServiceSetter
	private GroupIndexService groupIndexService;
	@ServiceSetter
	private UserGroupListDao userGroupListDao;
	@ServiceSetter
	private GroupSubscriptionManager subscriptionManager;
	@ServiceSetter
	private GroupTerminalService groupTerminalService;
	@ServiceSetter
	private EnumService enumService;
	@ServiceSetter
	private UserLocatorService userLocatorService;
	@ServiceSetter
	private GroupListVersionCacheManager groupListVersionCacheManager;
	@ServiceSetter
	private GroupInfoVersionCacheManager groupInfoVersionCacheManager;

	/**
	 * 通知的Task直接下发即可，无需走T端逻辑
	 */
	@TaskEvent(GroupTaskEvents.GROUP_INFO_NOTIFY)
	private TaskProducer<GroupInfoNotifyArgs> infoNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_LIST_NOTIFY)
	private TaskProducer<GroupListNotifyArgs> listNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_CREATE)
	private TaskProducer<FetionCreateGroupArgs> fetionCreateGroupTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_INVITE_MEMBER)
	private TaskProducer<FetionInviteArgs> fetionInviteTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_KICK_MEMBER)
	private TaskProducer<FetionKickGroupMemberArgs> fetionKickTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_MODIFY_SUBJECT)
	private TaskProducer<FetionModifyGroupNameArgs> fetionModifyGroupNameTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_MODIFY_MEMBER_CARD)
	private TaskProducer<FetionModifyMemberCardArgs> fetionModifyGroupMemberCardTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_CHANGE_ADMIN)
	private TaskProducer<FetionChangeAdminArgs> fetionChangeAdminTask;
	@TaskEvent(GroupTaskEvents.GROUP_FETION_BYE)
	private TaskProducer<FetionByeGroupArgs> fetionGroupByeTask;

	// PD Group Task
	@TaskEvent(GroupTaskEvents.GROUP_PD_CHANGE_ADMIN_NOTIFY)
	private TaskProducer<PdChangeGroupOwnerNotifyArgs> pdChangeGroupOwnerNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_DISMISS_NOTIFY)
	private TaskProducer<PdDeleteGroupNotifyArgs> pdDeleteGroupNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_INFO_NOTIFY)
	private TaskProducer<PdGroupInfoNotifyArgs> pdGroupInfoNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_INVITE_REPLY)
	private TaskProducer<PdGroupInviteReplyMessageArgs> pdGroupInviteReplyMessageTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_INVITE_REPLY_NOTIFY)
	private TaskProducer<PdGroupInviteReplyNotifyArgs> pdGroupInviteReplyNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_KICK_MEMBER_NOTIFY)
	private TaskProducer<PdRemoveGroupMemberNotifyArgs> pdRemoveGroupMemberNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_UPDATE_MEMBER_NAME_NOTIFY)
	private TaskProducer<PdUpdateGroupMemberNameNotifyArgs> pdUpdateGroupMemberNameNotifyTask;
	@TaskEvent(GroupTaskEvents.GROUP_PD_UPDATE_NAME_NOTIFY)
	private TaskProducer<PdUpdateGroupNameNotifyArgs> pdUpdateGroupNameNotifyTask;

	// And PC Server Task
	@TaskEvent(GroupTaskEvents.GROUP_INVITE_NOTIFY_TO_PC)
	private TaskProducer<AndPcGroupInviteNotifyArgs> groupInviteNotifyToPcTask;
	@TaskEvent(GroupTaskEvents.GROUP_INFO_NOTIFY_TO_PC)
	private TaskProducer<AndPcGroupInfoNotifyArgs> groupInfoNotifyToPcTask;
	@TaskEvent(GroupTaskEvents.GROUP_MEMBER_INFO_NOTIFY_TO_PC)
	private TaskProducer<AndPcGroupMemberInfoNotifyArgs> groupMemberInfoNotifyToPcTask;
	@TaskEvent(GroupTaskEvents.DISMISS_GROUP_NOTIFY_TO_PC)
	private TaskProducer<AndPcDismissGroupNotifyArgs> dismissGroupNotifyToPcTask;
	@TaskEvent(GroupTaskEvents.GROUP_LIST_NOTIFY_TO_PC)
	private TaskProducer<AndPcGroupListNotifyArgs> grouplistNotifyToPcTask;

	// 外域Task
	@TaskEvent(GroupTaskEvents.GROUP_INVITE)
	private TaskProducer<GroupInviteArgs> outterGroupInviteTask;
	@TaskEvent(GroupTaskEvents.GROUP_BYE)
	private TaskProducer<GroupByeArgs> outterByeTask;
	@TaskEvent(GroupTaskEvents.GROUP_SMS)
	private TaskProducer<GroupSmsArgs> inviteSmsTask;

	public GroupServiceImpl() {
	}


	@Override
	public GroupIndex getGroupIndex(int groupId) throws Exception {
		return groupIndexService.getGroupById(groupId);
	}

	/**
	 * P
	 * 1、conversationId是否存在
	 * 2、fromUri是否有创建群的权限及配额
	 *
	 * @param req
	 */
	@Override
	public GroupInfo checkAndCreate(CreateGroupArgs req) throws Exception {
		// 1. 检查群是否存在.
		MobileNo fromMobileNo = req.getFromMobileNo();
		String conversationId = req.getConversationId();
		GroupIndex groupIndex = groupIndexService.getGroupByConversationId(conversationId);

		if (groupIndex != null) {
			throw new GroupException(GroupError.CONVERSATION_ID_EXIST);
		}

		// 检查人是否打到群上限.或者没创建群的权限
		if (!userGroupListDao.canCreateGroup(fromMobileNo)) {
			throw new GroupException(GroupError.CAN_NOT_CREATE_MORE_GROUP);
		}

		groupIndex = groupIndexService.createGroup(conversationId, req.getSubject(), fromMobileNo);
		// 创建群并添加群成员10.10.40.106:5070
		groupDao.createGroup(groupIndex, fromMobileNo, conversationId, req.getSubject(), null);
		userGroupListDao.insertUserGroupList(fromMobileNo, groupIndex, 1);

		int grpListVer = groupListVersionCacheManager.incGrpListVer(fromMobileNo);
		// And PC send GroupList Notify
		AndPcGroupListNotifyArgs andPcGroupListNotifyArgs = new AndPcGroupListNotifyArgs();
		andPcGroupListNotifyArgs.setVersion(grpListVer);
		andPcGroupListNotifyArgs.setNotifyMember(req.getFromMobileNo());
		grouplistNotifyToPcTask.produce(andPcGroupListNotifyArgs);
		GroupInfo groupInfo = groupDao.getGroupInfo(groupIndex);

		//如果是PC 客户端创建,需要给自己的手机终端发一个激活的INVITE 信令.
		if (ClientType.PC.equals(req.getClientType())) {
			GroupMessageArgs groupMessageArgs = new GroupMessageArgs();
			groupMessageArgs.setGroupId(groupInfo.getGroupId());
			groupMessageArgs.setToMobile(fromMobileNo); // 接受者为自己
			groupMessageArgs.setDomain(GroupConfiguration.INSTANCE.getGroupDomain());
			groupMessageArgs.setConversationId(groupInfo.getConversationId());
			groupMessageArgs.setSubject(groupInfo.getSubject());
			groupMessageArgs.setIsOnlyActiveOfflineMsg(true); // 设置为仅仅激活群. 复用用激活离线消息下发的方式吧.
			groupTerminalService.sendTextMessage(groupMessageArgs);
		}

		if (fetionCreateGroupTask != null) {
			try {
				//飞信互通，调用飞信FetionGroupService ,需要在Task 中获取userid ,logicalPool 之类的飞信的必要参数.
				FetionCreateGroupArgs args = new FetionCreateGroupArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setOperatorMobileNo(fromMobileNo);
				groupArgs.setGroupLogicPool(groupIndex.getLogicalPool());
				groupArgs.setGroupId(groupIndex.getGroupId());
				args.setGroupName(groupInfo.getSubject());
				args.setGroup(groupArgs);
				fetionCreateGroupTask.produce(args);
			} catch (Exception e) {
				LOGGER.error("fetionCreateGroupTask or err  e", e);
			}
		} else {
			LOGGER.info("no interoperate  create Group");
		}
//		MobileNo[] members = new MobileNo[req.getMembers().size()];
//		req.getMembers().toArray(members);
//		inviteGroupMembers(groupIndex, fromMobileNo, members);
		return groupInfo;
	}


	/**
	 * 1、校验群是否存在
	 * 2、校验群是否存在fromMobileNo这个人
	 *
	 * @param fromMobileNo
	 * @param groupUri
	 * @throws GroupException
	 */
	@Override
	public void check(MobileNo fromMobileNo, String groupUri) throws Exception {

		if (null == groupUri || groupUri.trim().length() == 0) {
			throw new GroupException(GroupError.REQUEST_URI_REQUIRED);
		}
		GroupIndex index = groupIndexService.getGroupByUri(groupUri);
		if (index == null) {
			throw new GroupException(GroupError.GONE);
		}
		GroupInfo groupInfo = groupDao.getGroupInfo(index);

		if (null == groupInfo) {
			throw new GroupException(GroupError.GONE);
		}
		for (GroupMember member : groupInfo.getMembers()) {
			if (member.getMobileNo().equals(fromMobileNo)) {
				return;
			}
		}
		throw new GroupException(GroupError.GONE);
	}

	@Override
	public List<Integer> getGroupList(MobileNo mobileNo) throws Exception {
		List<GroupIndex> list = userGroupListDao.getUserGroupList(mobileNo);
		if (list != null) {
			return list.stream().map(e -> e.getGroupId()).collect(Collectors.toList());
		}
		return new ArrayList<>();
	}

	@Override
	public GroupInfo getGroupInfo(GroupIndex groupIndex) throws Exception {
		return groupDao.getGroupInfo(groupIndex);
	}

	@Override
	public void changeSubject(GroupCommonArgs req, String subject) throws Exception {
		 /*
		 * 检查群是否存在, 检查发起人是否为群主. 检查群名称是否合法.
         */
		GroupInfo groupInfo = null;
		MobileNo fromUserMobile = req.getFromMobileNo();

		// 检查群是否存在, 以及这厮是不是群管理.
		GroupIndex groupIndex = req.getGroupIndex();
		groupInfo = this.getGroupInfo(groupIndex);

		if (null == groupIndex || null == groupInfo) {
			throw new GroupException(GroupError.GONE);
		}
		// TODO 由于客户端上来的conversationId每次重新生成，所以在此用conversationId判断群唯一，有问题！
//            if (!groupInfo.getConversationId().equals(conversationId)) {
//                LOGGER.warn(String.format(" groupid =%s  fromUser=%s serverConversationId=%s clientConversation=%s",
//                        groupIndex.getGroupId(), fromUserMobile, groupInfo.getConversationId(), conversationId));
//                throw new GroupException(GroupError.GROUP_FORBIDDEN);
//            }

		// 检查是不是群主
		if (!groupInfo.getGroupAdmin().equals(fromUserMobile)) {
			throw new GroupException(GroupError.GROUPNAME_NOT_ALLOWED_BY_MOBITOR_PLAT);
		}
		//TODO 需要检查群名称 长度之类的
		groupDao.updateGroupSubject(groupIndex, subject);
		groupInfo = this.getGroupInfo(groupIndex);
		groupInfo.setSubject(subject);
		// 更新群版本号
		int currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(groupInfo.getGroupId());
		NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, groupInfo);
		// T端Group做PreDefined逻辑
		PdNotifyMembersHelper.updateGroupNameNotify(pdUpdateGroupNameNotifyTask,
				subscriptionManager,
				null,
				groupInfo.getGroupId(),
				GroupConfiguration.INSTANCE.getGroupDomain(),
				"",
				"",
				subject);

		try {
			// TODO And PC Server
			AndPcGroupInfoNotifyArgs andPcGroupInfoNotifyArgs = new AndPcGroupInfoNotifyArgs();
			andPcGroupInfoNotifyArgs.setGroupid(groupInfo.getGroupId());
			andPcGroupInfoNotifyArgs.setSubject(subject);
			List<MobileNo> notifyMembers = new ArrayList<>();
			groupInfo.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
			});
			andPcGroupInfoNotifyArgs.setNotifyMemberList(notifyMembers);
			andPcGroupInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0: currentVersion);
			andPcGroupInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
			groupInfoNotifyToPcTask.produce(andPcGroupInfoNotifyArgs);

		} catch (Exception ex) {
			LOGGER.error("AndPC ModifyGroupNameTask or groupInfoNotifyToPcTask ", ex);
		}
		try {
			//  飞信互通，调用飞信FetionGroupService
			if (fetionModifyGroupNameTask != null) {
				FetionModifyGroupNameArgs args = new FetionModifyGroupNameArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setGroupId(groupIndex.getGroupId());
				groupArgs.setGroupLogicPool(groupIndex.getLogicalPool());
				groupArgs.setOperatorMobileNo(fromUserMobile);
				args.setGroup(groupArgs);
				args.setGroupName(subject);
				fetionModifyGroupNameTask.produce(args);
			}
		} catch (Exception ex) {
			LOGGER.error("fetion ModifyGroupNameTask or groupInfoNotifyToPcTask ", ex);
		}
	}

	@Override
	public void updateGroupMemberNickname(GroupIndex index, MobileNo mobileNo, String nickName) throws Exception {
		groupDao.updateGroupMemberNickname(index, mobileNo, nickName);
		GroupInfo groupInfo = getGroupInfo(index);
		// 群版本号变更
		int currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(index.getGroupId());
		NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, groupInfo);
		PdNotifyMembersHelper.updateGroupMemberNameNotify(pdUpdateGroupMemberNameNotifyTask,
				subscriptionManager,
				null,
				groupInfo.getGroupId(),
				GroupConfiguration.INSTANCE.getGroupDomain(),
				"",
				"",
				mobileNo,
				nickName);
		try {
			// TODO And PC Server
			AndPcGroupMemberInfoNotifyArgs andPcGroupMemberInfoNotifyArgs = new AndPcGroupMemberInfoNotifyArgs();
			GroupMemberInfoArgs groupMemberInfo = new GroupMemberInfoArgs();
			List<MobileNo> notifyMembers = new ArrayList<>();
			groupInfo.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
				if (groupMember.getMobileNo().equals(mobileNo)) {
					groupMemberInfo.setIdentity(groupMember.getIdentity());
					groupMemberInfo.setMobileNo(groupMember.getMobileNo());
					groupMemberInfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
					groupMemberInfo.setStatus(2);
				}
			});
			andPcGroupMemberInfoNotifyArgs.setNotifyMemberList(notifyMembers);
			andPcGroupMemberInfoNotifyArgs.setGroupId(groupInfo.getGroupId());
			andPcGroupMemberInfoNotifyArgs.setPushMode(2);
			andPcGroupMemberInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0 : currentVersion);
			andPcGroupMemberInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
			List<GroupMemberInfoArgs> members = new ArrayList<>();
			members.add(groupMemberInfo);
			andPcGroupMemberInfoNotifyArgs.setMemberInfoList(members);
			groupMemberInfoNotifyToPcTask.produce(andPcGroupMemberInfoNotifyArgs);
		} catch (Exception ex) {
			LOGGER.error("andPC   groupMemberInfoNotifyToPcTask  error", ex);
		}
		try {
			//  飞信互通，调用飞信FetionGroupService
			if (fetionModifyGroupMemberCardTask != null) {
				FetionModifyMemberCardArgs args = new FetionModifyMemberCardArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setGroupId(index.getGroupId());
				groupArgs.setGroupLogicPool(index.getLogicalPool());
				groupArgs.setOperatorMobileNo(mobileNo);
				args.setGroup(groupArgs);
				args.setGroupNickName(nickName);
				fetionModifyGroupMemberCardTask.produce(args);
			}
		} catch (Exception ex) {
			LOGGER.error("fetion InviteTask  error ", ex);
		}

	}

	/**
	 * 用于邀请的成员的应答.
	 * change: 需要在此增加客户端类型, 如果来源的客户端类型为PC ,则对手机发送cancel , 反之亦然
	 *
	 * @param index
	 * @param memberMobile
	 * @param isAccept     true: 接受加入群 false: 拒绝加入群
	 * @param isPreDefined
	 * @throws Exception
	 */
	@Override
	public void processGroupInvite(GroupIndex index, MobileNo memberMobile, boolean isAccept, boolean isPreDefined) throws Exception {
		LOGGER.info("processGroupInvite {} {}", index.getGroupId(), memberMobile);
		ClientType clientType = null;

		GroupInfo info = getGroupInfo(index);
		int grpListVer = 0;
		int currentVersion = 0;
		if (isAccept) {

			for (GroupMember member : info.getMembers()) {
				if (memberMobile.equals(member.getMobileNo())) {
					if (member.getIdentity() == 61) {
						groupDao.acceptGroupMemberInvitation(index, memberMobile);
						break;
					}
				}
			}
//			cancelInvite(info,memberMobile,ClientType.PC);
//			groupDao.acceptGroupMemberInvitation(index, memberMobile);
			info = getGroupInfo(index);
			if (null == info) {
				throw new GroupException(GroupError.GONE);
			}
			if (!memberMobile.equals(info.getGroupAdmin())) {
				userGroupListDao.updateUserGroupIdentity(memberMobile, index, 3);
			}
			try {
				// TODO 飞信互通，调用飞信FetionGroupService
				if (fetionInviteTask != null) {

					FetionInviteArgs fetionInviteArgs = new FetionInviteArgs();
					FetionGroupArgs groupArgs = new FetionGroupArgs();
					groupArgs.setGroupId(index.getGroupId());
					groupArgs.setOperatorMobileNo(memberMobile);
					groupArgs.setGroupLogicPool(index.getLogicalPool());
					groupArgs.setOperateType(OperateType.AcceptGroupInvite.intValue());
					fetionInviteArgs.setInviteeMobileNo(memberMobile);
					fetionInviteArgs.setGroup(groupArgs);
					fetionInviteTask.produce(fetionInviteArgs);
				}
			} catch (Exception ex) {
				LOGGER.error("fetionInviteTask error :{}", ex);
			}
			// pc同意后，给手机下发cancle，复用inviteTask
			if (isPreDefined) {
				GroupInviteArgs a = new GroupInviteArgs();
				a.setReferredTo(memberMobile);
				a.setGroupId(info.getGroupId());
				a.setCancel(true);
				outterGroupInviteTask.produce(a);
			}

			grpListVer = groupListVersionCacheManager.incGrpListVer(memberMobile);
			currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(info.getGroupId());
		} else {
			groupDao.deleteGroupMember(index, memberMobile);
			userGroupListDao.deleteUserGroupList(memberMobile, index);

		}
		NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, info);
//		NotifyMembersHelper.notifyGroupListToMember(listNotifyTask, subscriptionManager, info, memberMobile);

		MobileNo inviterMobile = null;
		for (GroupMember member : info.getMembers()) {
			if (member.getMobileNo().equals(memberMobile)) {
				inviterMobile = member.getReferBy();
				break;
			}
		}
		if (inviterMobile != null) {
			PdNotifyMembersHelper.groupInviteReplyMessage(pdGroupInviteReplyMessageTask,
					info.getGroupId(),
					GroupConfiguration.INSTANCE.getGroupDomain(),
					info.getSubject(),
					info.getGroupAdmin(),
					info.getConversationId(),
					inviterMobile,
					memberMobile,
					isAccept ? "yes" : "no");
		}
		try {
			if (isAccept) {
				// TODO PD
				PdNotifyMembersHelper.groupInviteReplyNotify(pdGroupInviteReplyNotifyTask,
						subscriptionManager,
						null,
						info.getGroupId(),
						GroupConfiguration.INSTANCE.getGroupDomain(),
						"",
						"",
						memberMobile,
						"");

				// TODO And PC Server
				AndPcGroupMemberInfoNotifyArgs andPcGroupMemberInfoNotifyArgs = new AndPcGroupMemberInfoNotifyArgs();
				GroupMemberInfoArgs groupMemberInfo = new GroupMemberInfoArgs();
				List<MobileNo> notifyMembers = new ArrayList<>();
				info.getMembers().forEach(groupMember -> {
					if (groupMember.getIdentity() != 61) {
						notifyMembers.add(groupMember.getMobileNo());
					}
					if (groupMember.getMobileNo().equals(memberMobile)) {
						groupMemberInfo.setIdentity(groupMember.getIdentity());
						groupMemberInfo.setMobileNo(groupMember.getMobileNo());
						groupMemberInfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
						groupMemberInfo.setStatus(2);
					}
				});
				andPcGroupMemberInfoNotifyArgs.setNotifyMemberList(notifyMembers);
				andPcGroupMemberInfoNotifyArgs.setGroupId(info.getGroupId());
				andPcGroupMemberInfoNotifyArgs.setPushMode(2);
				List<GroupMemberInfoArgs> members = new ArrayList<>();
				members.add(groupMemberInfo);
				andPcGroupMemberInfoNotifyArgs.setMemberInfoList(members);
				andPcGroupMemberInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
				andPcGroupMemberInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0 : currentVersion);
				groupMemberInfoNotifyToPcTask.produce(andPcGroupMemberInfoNotifyArgs);

				AndPcGroupListNotifyArgs andPcGroupListNotifyArgs = new AndPcGroupListNotifyArgs();
				andPcGroupListNotifyArgs.setNotifyMember(memberMobile);
				andPcGroupListNotifyArgs.setVersion(grpListVer);
				grouplistNotifyToPcTask.produce(andPcGroupListNotifyArgs);
			}
		} catch (Exception e) {
			LOGGER.error("invoke And PC Server occur error :{}", e);
		}

	}

	@Override
	public void inviteGroupMembers(GroupIndex index, MobileNo referBy, MobileNo... invitees) throws Exception {
		//TODO: 处理超限，逗你玩模式等
		List<MobileNo> inviteesTask = new ArrayList<>();
		GroupInfo info = groupDao.getGroupInfo(index);
		GroupInfo groupInfo = getGroupInfo(index);
		if (groupInfo == null) {
			throw new GroupException(GroupError.GONE);
		}

		for (MobileNo invitee : invitees) {

			if (groupInfo.getCurrentMemberCount() >= GroupConfiguration.INSTANCE.getMemberLimit()) {
				throw new GroupException(GroupError.TOO_MANY_PARTICIPANTS);
			}

			if (invitee.equals(referBy)) continue; // 不能邀请自己

			if (invitee.equals(info.getGroupAdmin())) continue; // 不能邀请管理

			try {
				int identity = groupDao.inviteGroupMember(index, referBy, invitee);
				if (identity == -1) {
					userGroupListDao.insertUserGroupList(invitee, index, 61);
				}
				if (identity == -1 || identity == 61) {
					inviteesTask.add(invitee);
				}
			} catch (Exception e) {
				LOGGER.error(String.format("invitee Error index=%s,referBy=%s,invitee=%s", index.toJsonObject().toString(), referBy.toString(), invitee.toString()), e);
			}
		}


		for (MobileNo invitee : inviteesTask) {
			// 原有代码实现
			GroupInviteArgs entity = new GroupInviteArgs();
			entity.setConversationId(info.getConversationId());
			entity.setGroupId(info.getGroupId());
			entity.setSubject(info.getSubject());
			entity.setDomain(GroupConfiguration.INSTANCE.getGroupDomain());
			entity.setReferredBy(referBy);
			entity.setReferredTo(invitee);
			// 查询目标用户所在域
			SipURI uri = (SipURI) enumService.getSipURI(invitee);
			if (uri == null) {
				LOGGER.error(String.format("invite member EnumService getSipURI is null  user=%s", invitee));
				// 你被XXX邀请加入YYY群，请下载融合通信客户端APP（URL）或更换支持融合通信的终端来加入该群聊
				GroupSmsArgs smsArgs = new GroupSmsArgs();
				smsArgs.setAppId("009");
				smsArgs.setDestMobileNo(invitee);
				smsArgs.setSrcMobileNo(referBy);
				String sms = String.format("你被%s邀请加入%s群，请下载融合通信客户端APP（URL）或更换支持融合通信的终端来加入该群聊", referBy, info.getSubject());
				smsArgs.setText(sms);
				inviteSmsTask.produce(smsArgs);
				outterGroupInviteTask.produce(entity);
				continue;
			} else {
				boolean isLocal = userLocatorService.lookup(invitee).getType().equals(UserType.INNER);
				if (isLocal) {
					// 设计为GroupTerminal的实现
					groupTerminalService.inviteJoinGroup(entity);
				} else {
					outterGroupInviteTask.produce(entity);
				}
			}
			try {
				// 飞信互通，调用飞信FetionGroupService
				if (fetionInviteTask != null) {
					FetionInviteArgs fetionInviteArgs = new FetionInviteArgs();
					FetionGroupArgs groupArgs = new FetionGroupArgs();
					groupArgs.setGroupId(index.getGroupId());
					groupArgs.setOperatorMobileNo(referBy);
					groupArgs.setGroupLogicPool(index.getLogicalPool());
					groupArgs.setOperateType(OperateType.InviteMemberJoinGroup.intValue());
					fetionInviteArgs.setInviteeMobileNo(invitee);
					fetionInviteArgs.setGroup(groupArgs);
					fetionInviteTask.produce(fetionInviteArgs);
				} else {
					LOGGER.info("no fetionInviteTask  invite Group");
				}
			} catch (Exception ex) {
				LOGGER.error("invite member,   error ", ex);
			}
			try {
				// TODO And PC Server
				AndPcGroupInviteNotifyArgs andPcGroupInviteNotifyArgs = new AndPcGroupInviteNotifyArgs();
				andPcGroupInviteNotifyArgs.setSubject(info.getSubject());
				andPcGroupInviteNotifyArgs.setConversationId(info.getConversationId());
				andPcGroupInviteNotifyArgs.setDomain(GroupConfiguration.INSTANCE.getGroupDomain());
				andPcGroupInviteNotifyArgs.setGroupId(info.getGroupId());
				andPcGroupInviteNotifyArgs.setReferByMobileNo(referBy);
				andPcGroupInviteNotifyArgs.setReferToMobileNo(invitee);
				info.getMembers().forEach(groupMember -> {
					if (groupMember.getMobileNo().equals(referBy)) {
						andPcGroupInviteNotifyArgs.setReferByName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? referBy.getMobile() : groupMember.getDisplayname());
					} else {
						return;
					}
				});
				groupInviteNotifyToPcTask.produce(andPcGroupInviteNotifyArgs);
			} catch (Exception ex) {
				LOGGER.error("invite member, fx interop or pc server error :{}", ex);
			}
		}
	}

	@Override
	public void removeGroupMembers(GroupIndex index, MobileNo referBy, MobileNo... members) throws Exception {
		for (MobileNo member : members) {
			GroupInfo info = groupDao.getGroupInfo(index);
			// 先给被踢的人 发一个bye,
			GroupByeArgs args = new GroupByeArgs();
			args.setGroupId(index.getGroupId());
			args.setCause(200);
			args.setToMember(member);
			args.setText("Booted"); // 被踢 Booted
			SipURI uri = (SipURI) enumService.getSipURI(member);
			if (uri == null) {
				LOGGER.error(String.format("removeGroupMembers member EnumService getSipURI is null  user=%s", member));
				continue;
			} else {
				boolean isLocal = userLocatorService.lookup(member).getType().equals(UserType.INNER);
				if (isLocal) {
					groupTerminalService.kickMember(args);
				} else {
					outterByeTask.produce(args);
				}
			}
			// 给出了被踢人外的其他人发notify
			NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, info, member, GroupInfoNotifyType.DELETED, false, member);
			int grpListVer = groupListVersionCacheManager.incGrpListVer(member);
			NotifyMembersHelper.notifyGroupListToMember(listNotifyTask, subscriptionManager, info, member);
			PdNotifyMembersHelper.removeGroupMemberNotify(pdRemoveGroupMemberNotifyTask,
					subscriptionManager,
					member,
					info.getGroupId(),
					GroupConfiguration.INSTANCE.getGroupDomain(),
					"",
					"",
					member);

			//真正删除这个人,
			groupDao.deleteGroupMember(index, member);
			userGroupListDao.deleteUserGroupList(member, index);
			int currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(index.getGroupId());
			AndPcGroupMemberInfoNotifyArgs andPcGroupMemberInfoNotifyArgs = new AndPcGroupMemberInfoNotifyArgs();
			GroupMemberInfoArgs groupMemberInfo = new GroupMemberInfoArgs();
			List<MobileNo> notifyMembers = new ArrayList<>();
			info.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
				if (groupMember.getMobileNo().equals(member)) {
					groupMemberInfo.setIdentity(groupMember.getIdentity());
					groupMemberInfo.setMobileNo(groupMember.getMobileNo());
					groupMemberInfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
					groupMemberInfo.setStatus(5);
				}
			});
			andPcGroupMemberInfoNotifyArgs.setNotifyMemberList(notifyMembers);
			andPcGroupMemberInfoNotifyArgs.setGroupId(info.getGroupId());
			andPcGroupMemberInfoNotifyArgs.setPushMode(2);
			List<GroupMemberInfoArgs> memberList = new ArrayList<>();
			memberList.add(groupMemberInfo);
			andPcGroupMemberInfoNotifyArgs.setMemberInfoList(memberList);
			andPcGroupMemberInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
			andPcGroupMemberInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0 : currentVersion);
			groupMemberInfoNotifyToPcTask.produce(andPcGroupMemberInfoNotifyArgs);
			AndPcGroupListNotifyArgs andPcGroupListNotifyArgs = new AndPcGroupListNotifyArgs();
			andPcGroupListNotifyArgs.setNotifyMember(member);
			andPcGroupListNotifyArgs.setVersion(grpListVer);
			grouplistNotifyToPcTask.produce(andPcGroupListNotifyArgs);
			try {
				// 飞信互通，调用飞信FetionGroupService
				if (fetionKickTask != null) {
					FetionKickGroupMemberArgs kickGroupMemberArgs = new FetionKickGroupMemberArgs();
					FetionGroupArgs groupArgs = new FetionGroupArgs();
					groupArgs.setGroupId(index.getGroupId());
					groupArgs.setGroupLogicPool(index.getLogicalPool());
					groupArgs.setOperatorMobileNo(referBy);
					kickGroupMemberArgs.setGroup(groupArgs);
					kickGroupMemberArgs.setGroupMemberMobileNo(member);

					fetionKickTask.produce(kickGroupMemberArgs);
				} else {
					LOGGER.info("no interoperate  invite Group");
				}
			} catch (Exception ex) {
				LOGGER.error("fetionKickTask erro :{}", ex);
			}

			// 删除被踢人的订阅点
			subscriptionManager.unsubscribeConference(index.getGroupId(), member);
			subscriptionManager.unsubscribeGroupList(member);
		}

		// 移除成员后只剩一人时解散群聊
		onlyOneDismissGrp(index);

	}

	private void onlyOneDismissGrp(GroupIndex index) {
		try {
			GroupInfo info = groupDao.getGroupInfo(index);
			int count = 0;
			MobileNo src = null;
			for (GroupMember member : info.getMembers()) {
				if (member.getIdentity() == 1 || member.getIdentity() == 3) {
					count ++;
				}
				if (member.getStatus().intValue() == 1) {
					src = member.getMobileNo();
				}
			}
			if (count <= 1) {
				dismissGroup(index, src);
			}
			subscriptionManager.unsubscribeGroupConference(info.getGroupId());
		} catch (Exception e) {
			LOGGER.warn("only one member, dismiss group error:{}", e);
		}
	}

	@Override
	public void dismissGroup(GroupIndex index, MobileNo referBy) throws Exception {
		if (!groupDao.isChairMan(index, referBy)) {
			// TODO 需要定义错误码
			throw new GroupException(GroupError.DESTINATION_MISS_GPMANAGE_CAPABILITY);
		}
		GroupInfo info = groupDao.getGroupInfo(index);
		try {

			// TODO 飞信互通，调用飞信FetionGroupService
			if (fetionGroupByeTask != null) {
				FetionByeGroupArgs fetionByeGroupArgs = new FetionByeGroupArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setOperateType(OperateType.Dismiss.intValue());
				groupArgs.setGroupId(index.getGroupId());
				groupArgs.setGroupLogicPool(index.getLogicalPool());
				groupArgs.setOperatorMobileNo(referBy);
				fetionByeGroupArgs.setGroup(groupArgs);
				fetionByeGroupArgs.setGroupName(info.getSubject());
				fetionByeGroupArgs.setMemberMobiles(info.getMembers());
				fetionByeGroupArgs.setGroupType(info.getGroupType());
				fetionGroupByeTask.produce(fetionByeGroupArgs);
			} else {
				LOGGER.info("no interoperate  dismiss Group");
			}
		} catch (Exception ex) {
			LOGGER.error("fetionGroupByeTask or dismissGroupNotifyToPcTask  :{}", ex);
		}

//		List<GroupMemberSubscription> subs = subscriptionManager.getMemberConferenceSubscriptions(info.getGroupId());
//		for (GroupMemberSubscription sub : subs) {
		for (GroupMember member : info.getMembers()) {
			// 只针对本类型的群订阅执行
//			if (!sub.getSubType().equals(GroupSubscribeType.AD_GROUP)) {
//				continue;
//			}
			// 先给被踢的人 发一个bye,
			GroupByeArgs args = new GroupByeArgs();
			args.setGroupId(index.getGroupId());
			args.setCause(200);
//			args.setToMember(sub.getUserMobile());
			args.setToMember(member.getMobileNo());
			args.setText("Call Completed"); // 解散群 Call Completed

			// 获取用户所在域
//			SipURI uri = (SipURI) enumService.getSipURI(sub.getUserMobile());
			SipURI uri = (SipURI) enumService.getSipURI(member.getMobileNo());
			if (uri == null) {
//				LOGGER.info(String.format("dismissGroup member EnumService getSipURI is null  user=%s", sub.getUserMobile()));
				LOGGER.error(String.format("dismissGroup member EnumService getSipURI is null  user=%s", member.getMobileNo()));
				continue;
			} else {
//				boolean isLocal = userLocatorService.lookup(sub.getUserMobile()).getType().equals(UserType.INNER);
				boolean isLocal = userLocatorService.lookup(member.getMobileNo()).getType().equals(UserType.INNER);
				if (isLocal) {
					// 设计为GroupTerminal的实现 TODO
					groupTerminalService.kickMember(args);
				} else {
					// TODO 外域逻辑
					outterByeTask.produce(args);
				}
			}
		}

		groupDao.dismissGroup(index);
		for (GroupMember member : info.getMembers()) {
			groupListVersionCacheManager.incGrpListVer(member.getMobileNo());
			userGroupListDao.deleteUserGroupList(member.getMobileNo(), index);
		}
		try {
			// TODO And PC Server
			AndPcDismissGroupNotifyArgs andPcDismissGroupNotifyArgs = new AndPcDismissGroupNotifyArgs();
			andPcDismissGroupNotifyArgs.setGroupId(info.getGroupId());
			List<MobileNo> notifyMembers = new ArrayList<>();
			info.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
			});
			andPcDismissGroupNotifyArgs.setNotifyMemberList(notifyMembers);
			dismissGroupNotifyToPcTask.produce(andPcDismissGroupNotifyArgs);
		} catch (Exception ex) {
			LOGGER.error("fetionGroupByeTask or dismissGroupNotifyToPcTask  :{}", ex);
		}
		// 全部执行完了 才能删除索引.
		groupIndexService.deleteGroup(index.getGroupId());

	}

	@Override
	public void changeAdmin(GroupIndex index, MobileNo referBy, MobileNo referTo) throws Exception {
		if (!groupDao.isChairMan(index, referBy)) {
			throw new GroupException(GroupError.SERVICE_NOT_AUTHORISED);
		}
		groupDao.changeGroupAdmin(index, referBy, referTo);
		userGroupListDao.updateUserGroupIdentity(referBy, index, 3);
		userGroupListDao.updateUserGroupIdentity(referTo, index, 1);
		GroupInfo info = groupDao.getGroupInfo(index);
		int currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(index.getGroupId());

		NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, info);
		PdNotifyMembersHelper.changeGroupOwnerNotify(pdChangeGroupOwnerNotifyTask,
				subscriptionManager,
				null,
				info.getGroupId(),
				GroupConfiguration.INSTANCE.getGroupDomain(),
				"",
				"",
				referBy,
				referTo);

		try {
			// TODO And PC Server
			AndPcGroupMemberInfoNotifyArgs andPcGroupMemberInfoNotifyArgs = new AndPcGroupMemberInfoNotifyArgs();
			GroupMemberInfoArgs referByMemberinfo = new GroupMemberInfoArgs();
			GroupMemberInfoArgs referToMemberinfo = new GroupMemberInfoArgs();
			List<MobileNo> notifyMembers = new ArrayList<>();
			info.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
				if (groupMember.getMobileNo().equals(referBy)) {
					referByMemberinfo.setIdentity(groupMember.getIdentity());
					referByMemberinfo.setMobileNo(groupMember.getMobileNo());
					referByMemberinfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
					referByMemberinfo.setStatus(2);
				}
				if (groupMember.getMobileNo().equals(referTo)) {
					referToMemberinfo.setIdentity(groupMember.getIdentity());
					referToMemberinfo.setMobileNo(groupMember.getMobileNo());
					referToMemberinfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
					referToMemberinfo.setStatus(2);
				}
			});
			andPcGroupMemberInfoNotifyArgs.setNotifyMemberList(notifyMembers);
			andPcGroupMemberInfoNotifyArgs.setGroupId(info.getGroupId());
			andPcGroupMemberInfoNotifyArgs.setPushMode(2);
			List<GroupMemberInfoArgs> members = new ArrayList<>();
			members.add(referByMemberinfo);
			members.add(referToMemberinfo);
			andPcGroupMemberInfoNotifyArgs.setMemberInfoList(members);
			andPcGroupMemberInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
			andPcGroupMemberInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0 : currentVersion);
			groupMemberInfoNotifyToPcTask.produce(andPcGroupMemberInfoNotifyArgs);

			// TODO 飞信互通，调用飞信FetionGroupService
			if (fetionChangeAdminTask != null) {
				FetionChangeAdminArgs args = new FetionChangeAdminArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setGroupId(index.getGroupId());
				groupArgs.setGroupLogicPool(index.getLogicalPool());
				groupArgs.setOperateType(OperateType.Dismiss.intValue());
				groupArgs.setOperatorMobileNo(referBy);
				args.setGroup(groupArgs);
				args.setMemberMobileNo(info.getGroupAdmin());
				fetionChangeAdminTask.produce(args);
			}
		} catch (Exception ex) {
			LOGGER.error("fetionChangeAdminTask or groupMemberInfoNotifyToPcTask  :{}", ex);
		}
	}

	/**
	 * 退出群, 不能是管理员.管理员走解散群逻辑
	 *
	 * @param index
	 * @param referBy
	 * @throws Exception
	 */
	@Override
	public void quitGroup(GroupIndex index, MobileNo referBy) throws Exception {
		if (groupDao.isChairMan(index, referBy)) {
			throw new GroupException(GroupError.SERVICE_NOT_AUTHORISED);
		}
		//TODO 需要验证是不是本群成员
		GroupInfo info = groupDao.getGroupInfo(index);
		groupDao.deleteGroupMember(index, referBy);
		userGroupListDao.deleteUserGroupList(referBy, index);
		NotifyMembersHelper.notifyGroupInfoToMembers(infoNotifyTask, subscriptionManager, info, referBy, GroupInfoNotifyType.DELETED, false, referBy);
		int grpListVer = groupListVersionCacheManager.incGrpListVer(referBy);
		int currentVersion = groupInfoVersionCacheManager.incGrpInfoVer(index.getGroupId());
//		NotifyMembersHelper.notifyGroupListToMember(listNotifyTask, subscriptionManager, info, referBy);
		PdNotifyMembersHelper.removeGroupMemberNotify(pdRemoveGroupMemberNotifyTask,
				subscriptionManager,
				referBy,
				info.getGroupId(),
				GroupConfiguration.INSTANCE.getGroupDomain(),
				"",
				"",
				referBy);
		GroupByeArgs args = new GroupByeArgs();
		args.setText("Call completed");
		args.setCause(200);
		args.setGroupId(index.getGroupId());
		args.setToMember(referBy);
		outterByeTask.produce(args);
		subscriptionManager.unsubscribeConference(index.getGroupId(), referBy);
//		subscriptionManager.unsubscribeGroupList(referBy);
		try {
			// TODO And PC Server
			AndPcGroupMemberInfoNotifyArgs andPcGroupMemberInfoNotifyArgs = new AndPcGroupMemberInfoNotifyArgs();
			GroupMemberInfoArgs groupMemberInfo = new GroupMemberInfoArgs();
			List<MobileNo> notifyMembers = new ArrayList<>();
			info.getMembers().forEach(groupMember -> {
				if (groupMember.getIdentity() != 61) {
					notifyMembers.add(groupMember.getMobileNo());
				}
				if (groupMember.getMobileNo().equals(referBy)) {
					groupMemberInfo.setIdentity(groupMember.getIdentity());
					groupMemberInfo.setMobileNo(groupMember.getMobileNo());
					groupMemberInfo.setNickName(StringUtils.isNullOrEmpty(groupMember.getDisplayname()) ? groupMember.getMobileNo().getMobile() : groupMember.getDisplayname());
					groupMemberInfo.setStatus(4);
				}
			});
			andPcGroupMemberInfoNotifyArgs.setNotifyMemberList(notifyMembers);
			andPcGroupMemberInfoNotifyArgs.setGroupId(info.getGroupId());
			andPcGroupMemberInfoNotifyArgs.setPushMode(2);
			List<GroupMemberInfoArgs> members = new ArrayList<>();
			members.add(groupMemberInfo);
			andPcGroupMemberInfoNotifyArgs.setMemberInfoList(members);
			andPcGroupMemberInfoNotifyArgs.setPreviousVersion(currentVersion - 1 < 0 ? 0 : currentVersion - 1);
			andPcGroupMemberInfoNotifyArgs.setCurrentVersion(currentVersion < 0 ? 0 : currentVersion);
			groupMemberInfoNotifyToPcTask.produce(andPcGroupMemberInfoNotifyArgs);

			AndPcGroupListNotifyArgs andPcGroupListNotifyArgs = new AndPcGroupListNotifyArgs();
			andPcGroupListNotifyArgs.setNotifyMember(referBy);
			andPcGroupListNotifyArgs.setVersion(grpListVer);
			grouplistNotifyToPcTask.produce(andPcGroupListNotifyArgs);
			// TODO 飞信互通，调用飞信FetionGroupService
			if (fetionCreateGroupTask != null) {
				FetionByeGroupArgs fetionByeGroupArgs = new FetionByeGroupArgs();
				FetionGroupArgs groupArgs = new FetionGroupArgs();
				groupArgs.setOperateType(OperateType.QuitGroup.intValue());
				groupArgs.setOperatorMobileNo(referBy);
				groupArgs.setGroupLogicPool(index.getLogicalPool());
				groupArgs.setGroupId(index.getGroupId());
				fetionByeGroupArgs.setGroup(groupArgs);
				fetionGroupByeTask.produce(fetionByeGroupArgs);
			}

		} catch (Exception ex) {
			LOGGER.error("  fetionGroupByeTask or groupMemberInfoNotifyToPcTask  :{}", ex);
		}

		// 成员退出后只剩一人时解散群聊
		onlyOneDismissGrp(index);
	}

//	private boolean getLocalDomain(MobileNo mobileNo) {
//		String mobile = mobileNo.getMobile();
//		if (mobile.contains("1342624") || mobile.contains("13846978") || mobile.contains("136000") || mobile.contains("160000")) {
//			return true;
//		}
//		return false;
//	}


	@Override
	public void silenced(int groupId) throws Exception {

		try {
			GroupIndex gindex = getGroupIndex(groupId);
			// 如果群已经不存在, 则直接返回.
			if (null == gindex) return;
			GroupInfo info = groupDao.getGroupInfo(gindex);
			for (GroupMember member : info.getMembers()) {
				// TODO  需要给发一个bye .但是前提是得存在dialog, 如果dialog 不存在就不用管了 .
				GroupByeArgs args = new GroupByeArgs();
				args.setGroupId(gindex.getGroupId());
				args.setCause(408);
				args.setToMember(member.getMobileNo());
				args.setText("Request Timeout"); // 被踢 Booted
				SipURI uri = (SipURI) enumService.getSipURI(member.getMobileNo());
				if (uri == null) {
					LOGGER.error(String.format("silenced   uri is null  GroupId=%s, MobileNo=%s ", info.getGroupId(), member));
					continue;
				}
				boolean isLocal = userLocatorService.lookup(member.getMobileNo()).getType().equals(UserType.INNER);
				if (isLocal) {
					groupTerminalService.silenced(args);
					continue;
				}
				// TODO 外域逻辑
				outterByeTask.produce(args);
			}

		} catch (Exception e) {
			LOGGER.error(String.format("silenced Group Error  groupId:%s", groupId), e);
		}


	}

	@Override
	public void byeGroup(int groupId, MobileNo fromMobileNo, boolean isOnlyClean) {
		//TODO 需要和其他的bye 合并, 先这么放着
		GroupByeArgs args = new GroupByeArgs();
		args.setGroupId(groupId);
		args.setCause(200);
		args.setToMember(fromMobileNo);
		args.setText(""); // 被踢 Booted
		args.setOnlyClean(isOnlyClean);

		try {
			SipURI uri = (SipURI) enumService.getSipURI(fromMobileNo);
			if (uri == null) {
				LOGGER.info(String.format("byeGroup member EnumService getSipURI is null  user=%s", fromMobileNo));
				return;
			} else {
				boolean isLocal = userLocatorService.lookup(fromMobileNo).getType().equals(UserType.INNER);
				if (isLocal) {
					groupTerminalService.silenced(args);
				} else {
					outterByeTask.produce(args);
				}
			}
		} catch (Exception e) {
			LOGGER.error(String.format("bye error MobileNo=%s GroupID=%s", fromMobileNo, groupId), e);
		}
	}

}
